package com.brush.brushcommon.common.basic.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.brush.brushcommon.common.basic.mapper.CategoryMapper;
import com.brush.brushcommon.common.basic.mapper.CategoryOfSysquestionMapper;
import com.brush.brushcommon.common.basic.pojo.Category;
import com.brush.brushcommon.common.basic.pojo.CategoryOfSysquestion;
import com.brush.brushcommon.common.basic.service.CategoryOfSysquestionService;
import com.brush.brushcommon.common.basic.service.CategoryService;
import com.brush.brushcommon.dto.Result;
import com.brush.brushcommon.redis.service.RedisService;
import com.brush.brushcommon.utils.CategoryRecursion;
import com.brush.brushcommon.vo.basic.CategoryVo;
import jakarta.annotation.Resource;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.brush.brushcommon.common.mq.ExchangeConstants.*;
import static com.brush.brushcommon.redis.RedisConstants.BASIC_CATEGORY_KEY;
import static com.brush.brushcommon.redis.RedisConstants.BASIC_CATEGORY_TTL;

/**
 * <p>
 * 题库分类表 服务实现类
 * </p>
 *
 * @author debug
 * @since 2024-07-14
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {


    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private CategoryOfSysquestionService categoryOfSysquestionService;


    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 分类tree
     *
     * @param categoryName
     * @return
     */
    @Override
    public Result treeList(String categoryName) {
        if (StrUtil.isNotBlank(categoryName)) {
            List<Category> list = super.list(new LambdaQueryWrapper<Category>().like(Category::getCategoryName, categoryName).eq(Category::getIsDeleted, 0));
            List<CategoryVo> collect = list.stream().map(item -> {
                CategoryVo categoryVo = new CategoryVo();
                categoryVo.setChildren(Collections.emptyList());
                BeanUtil.copyProperties(item, categoryVo);
                return categoryVo;
            }).collect(Collectors.toList());
            return Result.success(collect);
        } else {
            if (stringRedisTemplate.hasKey(BASIC_CATEGORY_KEY)) {
                String res = stringRedisTemplate.opsForValue().get(BASIC_CATEGORY_KEY);
                List<CategoryVo> categoryVos = JSONUtil.toList(res, CategoryVo.class);
                return Result.success(categoryVos);
            }
            //转为 tree
            List<CategoryVo> recursion = CategoryRecursion.recursion(super.list(new LambdaQueryWrapper<Category>()
                    .like(Category::getCategoryName, categoryName)
                    .eq(Category::getIsDeleted, 0)));
            //        存入Redis
            stringRedisTemplate.opsForValue().set(BASIC_CATEGORY_KEY, JSONUtil.toJsonStr(recursion), BASIC_CATEGORY_TTL, TimeUnit.SECONDS);
            return Result.success(recursion);
        }
    }


    /**
     * @param category
     * @return Result
     * @date 2024/8/2 14:14
     * @description 添加分类
     */
    @Override
    public Result addCategory(Category category) {
        if (StrUtil.isBlank(category.getCategoryName())) {
            return Result.fail("分类名称不能为空");
        }
        if (StrUtil.isBlank(category.getParentId())) {
            return Result.fail("ParentId不能为空");
        }
//        情况redis
        stringRedisTemplate.delete(BASIC_CATEGORY_KEY);
        return save(category) ? Result.success("添加成功") : Result.fail("添加失败");
    }

    /**
     * @param category
     * @return Result
     * @author cws
     * @date 2024/8/2 15:16
     * @description 修改分类
     */
    @Override
    public Result updateCategory(Category category) {
        if (StrUtil.isBlank(category.getCategoryName())) {
            return Result.fail("分类名称不能为空");
        }
        if (StrUtil.isBlank(category.getParentId())) {
            return Result.fail("ParentId不能为空");
        }
        if (StrUtil.isBlank(category.getId())) {
            return Result.fail("Id不能为空");
        }
        //        情况redis
        stringRedisTemplate.delete(BASIC_CATEGORY_KEY);
        return updateById(category) ? Result.success("添加成功") : Result.fail("添加失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deleteCategory(String id) {
//        无子集即可删除
        Long count = lambdaQuery().eq(Category::getParentId, id).count();
        if(count>0){
            return Result.fail("该分类下有子集，无法删除,请先删除子集");
        }
        removeById(id);
//        删除绑定的题库
        categoryOfSysquestionService.remove(new LambdaQueryWrapper<CategoryOfSysquestion>().eq(CategoryOfSysquestion::getCategoryId, id));
//       清空redis
        stringRedisTemplate.delete(BASIC_CATEGORY_KEY);
        return Result.success();
    }

    @Override
    public Result deleteCategoryBatch(List<String> ids) {
//       批量删除
        boolean res = removeBatchByIds(ids);
        if(res){
            //       清空redis
            stringRedisTemplate.delete(BASIC_CATEGORY_KEY);
//       如果绑架题库较多删除交慢 直接交于MQ异步删除
            rabbitTemplate.convertAndSend(EXCHANGE_DELETE_CATEGORY, ROUTING_KEY_DELETE_CATEGORY, ids);
        }
        return Result.success();
    }

}
